﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using StockFinder.Model;

namespace StockFinder.TradingSystems
{
    public class TradingSystemResult
    {
        private List<Trade> _Trades;
        public List<Trade> Trades
        {
            get { return _Trades ?? (_Trades = new List<Trade>()); }
        }

        private decimal[] GetRs()
        {
            return Trades.Select(p => p.R).ToArray();
        }

        public decimal GetExpectancy()
        {
            return (Trades.Count == 0) ? 0 : GetRs().Average();
        }

        public double GetStandardDeviation()
        {
            var sd = 0d;

            if (Trades.Count > 0)
            {
                var rs = GetRs();
                var expectancy = GetExpectancy();
                var sumOfSquaresOfDifferences = GetRs().Select(val => (val - expectancy) * (val - expectancy)).Sum();
                sd = Math.Sqrt(Convert.ToDouble(sumOfSquaresOfDifferences) / rs.Length);                
            }
            
            return sd;
        }

        public double GetSqn()
        {
            var sqn = 0d;

            if (Trades.Count > 0)
            {
                var expectancy = GetExpectancy();
                var sd = GetStandardDeviation();
                sqn = (Convert.ToDouble(expectancy)/sd)*Math.Sqrt(Trades.Count);
            }

            return sqn;
        }

        public string AsCsv()
        {
            var output = new StringBuilder();

            //add column header row
            output.Append("Symbol,EntryDate,EntryPrice,ExitDate,ExitPrice,DaysInPosition,PnL,R");

            if (Trades.Count > 0)
            {
                //use first trade for header row
                var firstTrade = Trades.First();

                foreach (var stateAtEntryKey in firstTrade.StateAtEntry.Keys)
                {
                    output.Append("," + stateAtEntryKey);
                }

                output.AppendLine();

                foreach (var trade in Trades)
                {
                    output.AppendFormat(string.Format("{0},{1},{2},{3},{4},{5},{6},{7}",
                                                           trade.Symbol,
                                                           trade.EntryDate.ToString("dd/MM/yyyy"),
                                                           Math.Round(trade.EntryPrice, 2),
                                                           trade.ExitDate.ToString("dd/MM/yyyy"),
                                                           Math.Round(trade.ExitPrice, 2),
                                                           trade.DaysInPosition,
                                                           trade.PnL,
                                                           trade.R));

                    if (trade.StateAtEntry.Keys.Count > 0)
                    {
                        //then add dynamic state at entry details
                        for (int i = 0; i < trade.StateAtEntry.Keys.Count; i++)
                        {
                            var stateAtEntryKey = trade.StateAtEntry.Keys.ElementAt(i);
                            var stateAtEntryValue = Math.Round(trade.StateAtEntry[stateAtEntryKey], 2);

                            output.Append("," + stateAtEntryValue);
                        }
                    }

                    output.AppendLine();
                }
            }

            return output.ToString();
        }
    }
}
